package se.perp.c4.ui;

import java.awt.Point;
import java.awt.Polygon;
import java.util.HashMap;
import java.util.Map;
import se.perp.c4.model.Actor.Side;
import se.perp.c4.model.Territory.ETerritory;
import static se.perp.c4.model.Territory.ETerritory.*;

public class RegionBounds {

    private static Map<ETerritory, Polygon> bounds = new HashMap<ETerritory, Polygon>();
    private static Map<ETerritory, Polygon> flipBounds = new HashMap<ETerritory, Polygon>();
    private static Map<ETerritory, Polygon> current = bounds;
    private static int dx = 0,  dy = 0;

    public static void setDX(int dx) {
        RegionBounds.dx = dx;
        calculate();
    }

    public static void setDY(int dy) {
        RegionBounds.dy = dy;
        calculate();
    }

    static void setHomeSide(Side side) {
        current = (side == Side.LIGHT ? bounds : flipBounds);
    }

    static Side getHomeSide() {
        return (current == bounds ? Side.LIGHT : Side.DARK);
    }


    static {
        calculate();
    }

    public static Point getCenterPoint(ETerritory et) {
        Polygon p = get(et);
        int xsum = 0, ysum = 0;
        for (int i = 0; i < p.npoints; i++) {
            xsum += p.xpoints[i];
            ysum += p.ypoints[i];
        }
        return new Point(xsum / p.npoints, ysum / p.npoints);
    }

    private static void calculate() {
        bounds.put(NOWHERE, new Polygon());

        bounds.put(SHIRE, new Polygon(
                new int[]{194 + dx, 404 + dx, 299 + dx}, new int[]{494 + dy, 494 + dy, 599 + dy}, 3));

        bounds.put(ARTHEDAIN, new Polygon(
                new int[]{115 + dx, 194 + dx, 299 + dx, 299 + dx}, new int[]{414 + dy, 494 + dy, 494 + dy, 414 + dy}, 4));
        bounds.put(CARDOLAN, new Polygon(
                new int[]{299 + dx, 299 + dx, 404 + dx, 484 + dx}, new int[]{414 + dy, 494 + dy, 494 + dy, 414 + dy}, 4));

        bounds.put(RHUDAUR, new Polygon(
                new int[]{35 + dx, 224 + dx, 224 + dx, 115 + dx}, new int[]{334 + dy, 334 + dy, 414 + dy, 414 + dy}, 4));
        bounds.put(EREGION, new Polygon(
                new int[]{224 + dx, 224 + dx, 374 + dx, 374 + dx}, new int[]{334 + dy, 414 + dy, 414 + dy, 334 + dy}, 4));
        bounds.put(ENEDWAITH, new Polygon(
                new int[]{374 + dx, 374 + dx, 564 + dx, 484 + dx}, new int[]{414 + dy, 334 + dy, 334 + dy, 414 + dy}, 4));

        bounds.put(HIGHPASS, new Polygon(
                new int[]{35 + dx, 0 + dx, 35 + dx, 149 + dx, 149 + dx}, new int[]{264 + dy, 299 + dy, 334 + dy, 334 + dy, 264 + dy}, 5));
        bounds.put(MISTYMTS, new Polygon(
                new int[]{149 + dx, 149 + dx, 299 + dx, 299 + dx}, new int[]{264 + dy, 334 + dy, 334 + dy, 264 + dy}, 4));
        bounds.put(MORIA, new Polygon(
                new int[]{299 + dx, 299 + dx, 449 + dx, 449 + dx}, new int[]{334 + dy, 264 + dy, 264 + dy, 334 + dy}, 4));
        bounds.put(GAPOFROHAN, new Polygon(
                new int[]{564 + dx, 599 + dx, 564 + dx, 449 + dx, 449 + dx}, new int[]{264 + dy, 299 + dy, 334 + dy, 334 + dy, 264 + dy}, 5));

        bounds.put(MIRKWOOD, new Polygon(
                new int[]{35 + dx, 224 + dx, 224 + dx, 115 + dx}, new int[]{264 + dy, 264 + dy, 184 + dy, 184 + dy}, 4));
        bounds.put(FANGORN, new Polygon(
                new int[]{224 + dx, 224 + dx, 374 + dx, 374 + dx}, new int[]{264 + dy, 184 + dy, 184 + dy, 264 + dy}, 4));
        bounds.put(ROHAN, new Polygon(
                new int[]{374 + dx, 374 + dx, 484 + dx, 564 + dx}, new int[]{264 + dy, 184 + dy, 184 + dy, 264 + dy}, 4));

        bounds.put(DAGORLAD, new Polygon(
                new int[]{115 + dx, 299 + dx, 299 + dx, 195 + dx}, new int[]{184 + dy, 184 + dy, 104 + dy, 104 + dy}, 4));
        bounds.put(GONDOR, new Polygon(
                new int[]{299 + dx, 299 + dx, 484 + dx, 403 + dx}, new int[]{104 + dy, 184 + dy, 184 + dy, 104 + dy}, 4));

        bounds.put(MORDOR, new Polygon(
                new int[]{195 + dx, 403 + dx, 299 + dx}, new int[]{104 + dy, 104 + dy, 0 + dy}, 3));


        flipBounds.put(NOWHERE, bounds.get(NOWHERE));
        flipBounds.put(MORDOR, bounds.get(SHIRE));
        flipBounds.put(GONDOR, bounds.get(ARTHEDAIN));
        flipBounds.put(DAGORLAD, bounds.get(CARDOLAN));
        flipBounds.put(ROHAN, bounds.get(RHUDAUR));
        flipBounds.put(FANGORN, bounds.get(EREGION));
        flipBounds.put(MIRKWOOD, bounds.get(ENEDWAITH));
        flipBounds.put(GAPOFROHAN, bounds.get(HIGHPASS));
        flipBounds.put(MORIA, bounds.get(MISTYMTS));
        flipBounds.put(MISTYMTS, bounds.get(MORIA));
        flipBounds.put(HIGHPASS, bounds.get(GAPOFROHAN));
        flipBounds.put(ENEDWAITH, bounds.get(MIRKWOOD));
        flipBounds.put(EREGION, bounds.get(FANGORN));
        flipBounds.put(RHUDAUR, bounds.get(ROHAN));
        flipBounds.put(CARDOLAN, bounds.get(DAGORLAD));
        flipBounds.put(ARTHEDAIN, bounds.get(GONDOR));
        flipBounds.put(SHIRE, bounds.get(MORDOR));

    }

    public static Polygon get(ETerritory et) {
        return current.get(et);
    }

    public static ETerritory TerritoryIdAt(Point p) {
        return TerritoryIdAt(p.x, p.y);
    }

    public static ETerritory TerritoryIdAt(int x, int y) {
        for (ETerritory et : ETerritory.values()) {

            if (current.get(et).contains(x, y)) {
                return et;
            }
        }
        return null;
    }
}
